package com.kinyx.framework.processor;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.annotation.processing.FilerException;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.tools.FileObject;
import javax.tools.StandardLocation;

/**
 * 文件构建器
 */
public final class FileCreater {

	/** 构造方法 */
	private FileCreater() {}

	/**
	 * Creates a new source file and returns an object to allow
	 * writing to it.  The file's name and path (relative to the
	 * {@linkplain StandardLocation#SOURCE_OUTPUT root output location
	 * for source files}) are based on the type to be declared in that
	 * file.  If more than one type is being declared, the name of the
	 * principal top-level type (the public one, for example) should
	 * be used.  A source file can also be created to hold information
	 * about a package, including package annotations.  To create a
	 * source file for a named package, have {@code name} be the
	 * package's name followed by {@code ".package-info"}; to create a
	 * source file for an unnamed package, use {@code "package-info"}.
	 *
	 * <p> Note that to use a particular {@linkplain
	 * java.nio.charset.Charset charset} to encode the contents of the
	 * file, an {@code OutputStreamWriter} with the chosen charset can
	 * be created from the {@code OutputStream} from the returned
	 * object. If the {@code Writer} from the returned object is
	 * directly used for writing, its charset is determined by the
	 * implementation.  An annotation processing tool may have an
	 * {@code -encoding} flag or analogous option for specifying this;
	 * otherwise, it will typically be the platform's default
	 * encoding.
	 *
	 * <p>To avoid subsequent errors, the contents of the source file
	 * should be compatible with the {@linkplain
	 * ProcessingEnvironment#getSourceVersion source version} being used
	 * for this run.
	 *
	 * @param context 上下文环境
	 * @param content 文件内容
	 * @param name  canonical (fully qualified) name of the principal type
	 *          being declared in this file or a package name followed by
	 *          {@code ".package-info"} for a package information file
	 * @param originatingElements type or package elements causally
	 * associated with the creation of this file, may be elided or
	 * {@code null}
	 * @throws FilerException if the same pathname has already been
	 * created, the same type has already been created, or the name is
	 * not valid for a type
	 * @throws IOException if the file cannot be created
	 */
	public static void createSourceFile(final Context context, final String content, final String name, final Element... originatingElements) throws IOException {
		context.getLogger().NOTE("FileCreater.createSourceFile -> content\n" + content);
		final FileObject fo = context.getProcessingEnvironment().getFiler().createSourceFile(name, originatingElements);
		final OutputStream os = fo.openOutputStream();
		final PrintWriter pw = new PrintWriter(os);
		pw.println(content);
		pw.flush();
		pw.close();
	}

}
